/*
 * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package com.sun.corba.se.impl.presentation.rmi;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.Serializable;

import java.rmi.RemoteException;

import javax.rmi.CORBA.Tie;

import org.omg.CORBA_2_3.portable.ObjectImpl;

import org.omg.CORBA.portable.Delegate;
import org.omg.CORBA.portable.OutputStream;

import org.omg.CORBA.SystemException;
import org.omg.CORBA.ORB;

import com.sun.corba.se.spi.orbutil.proxy.InvocationHandlerFactory;
import com.sun.corba.se.spi.presentation.rmi.PresentationManager;
import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
import com.sun.corba.se.spi.presentation.rmi.DynamicStub;
import com.sun.corba.se.impl.presentation.rmi.StubConnectImpl;
import com.sun.corba.se.spi.logging.CORBALogDomains;
import com.sun.corba.se.impl.logging.UtilSystemException;
import com.sun.corba.se.impl.ior.StubIORImpl;
import com.sun.corba.se.impl.util.RepositoryId;
import com.sun.corba.se.impl.util.JDKBridge;
import com.sun.corba.se.impl.util.Utility;

// XXX Do we need _get_codebase?
public class DynamicStubImpl extends ObjectImpl
    implements DynamicStub, Serializable {

  private static final long serialVersionUID = 4852612040012087675L;

  private String[] typeIds;
  private StubIORImpl ior;
  private DynamicStub self = null;  // The actual DynamicProxy for this stub.

  public void setSelf(DynamicStub self) {
    // XXX Should probably only allow this once.
    this.self = self;
  }

  public DynamicStub getSelf() {
    return self;
  }

  public DynamicStubImpl(String[] typeIds) {
    this.typeIds = typeIds;
    ior = null;
  }

  public void setDelegate(Delegate delegate) {
    _set_delegate(delegate);
  }

  public Delegate getDelegate() {
    return _get_delegate();
  }

  public ORB getORB() {
    return (ORB) _orb();
  }

  public String[] _ids() {
    return typeIds;
  }

  public String[] getTypeIds() {
    return _ids();
  }

  public void connect(ORB orb) throws RemoteException {
    ior = StubConnectImpl.connect(ior, self, this, orb);
  }

  public boolean isLocal() {
    return _is_local();
  }

  public OutputStream request(String operation,
      boolean responseExpected) {
    return _request(operation, responseExpected);
  }

  private void readObject(ObjectInputStream stream) throws
      IOException, ClassNotFoundException {
    ior = new StubIORImpl();
    ior.doRead(stream);
  }

  private void writeObject(ObjectOutputStream stream) throws
      IOException {
    if (ior == null) {
      ior = new StubIORImpl(this);
    }
    ior.doWrite(stream);
  }

  public Object readResolve() {
    String repositoryId = ior.getRepositoryId();
    String cname = RepositoryId.cache.getId(repositoryId).getClassName();

    Class cls = null;

    try {
      cls = JDKBridge.loadClass(cname, null, null);
    } catch (ClassNotFoundException exc) {
      // XXX log this
    }

    PresentationManager pm =
        com.sun.corba.se.spi.orb.ORB.getPresentationManager();
    PresentationManager.ClassData classData = pm.getClassData(cls);
    InvocationHandlerFactoryImpl ihfactory =
        (InvocationHandlerFactoryImpl) classData.getInvocationHandlerFactory();
    return ihfactory.getInvocationHandler(this);
  }
}
